package com.imist.nettybasic4.server.handler;

import com.imist.nettybasic4.utils.SessionUtils;
import io.netty.channel.ChannelHandler;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;

@ChannelHandler.Sharable
public class AuthHandler extends ChannelInboundHandlerAdapter {
    public static final AuthHandler INSTANCE = new AuthHandler();

    protected AuthHandler() {

    }

    /**
     * 如果有很多业务逻辑的 handler 都要进行某些相同的操作，我们完全可以抽取出一个 handler 来单独处理
     * 如果某一个独立的逻辑在执行几次之后（这里是一次）不需要再执行了，那么我们可以通过 ChannelHandler
     * 的热插拔机制来实现动态删除逻辑，应用程序性能处理更为高效
     *
     *
     * 首先会判断是否登录成功，如果未登录，直接强制关闭连接（
     * 实际生产环境可能逻辑要复杂些，这里我们的重心在于学习 Netty，这里就粗暴些），
     * 否则，就把读到的数据向下传递，传递给后续指令处理器。
     * @param ctx
     * @param msg
     * @throws Exception
     */
    @Override
    public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
        if (!SessionUtils.hasLogin(ctx.channel())){
            ctx.channel().close();
        }else {
            //实现业务逻辑的删除,避免资源浪费，防止重复判断，验证成功之后，没有断开连接就不需要再重复验证了
            //从当前的连接的逻辑链中删除验证的逻辑
            ctx.pipeline().remove(this);
            super.channelRead(ctx, msg);
        }
    }

    @Override
    public void handlerRemoved(ChannelHandlerContext ctx) throws Exception {
        if (SessionUtils.hasLogin(ctx.channel())){
            System.out.println("当前连接登录验证完毕，无需再次验证，AuthHandler被移除");
        }else {
            System.out.println("没有登录验证，强制关闭连接!");
        }
    }
}
